/**
 * @description 计算字符串长度，全角按二个长度计算，半角按一个长度计算
 * @param {String} string 需要计算长度的字符串
 * @returns Object
 */
import numeral from 'numeral'
import moment from 'moment'
import { getUserInfo } from '@Config/server/localStorage'
import { keys, uniqueId } from 'lodash'

export let computedStringLength = (string = '') => {
  // eslint-disable-next-line no-control-regex
  let quanJiao = /[^\x00-\xff]/gi
  // eslint-disable-next-line no-control-regex
  let banJiao = /[\x00-\xff]/gi
  let quanJiaoMatch = string.match(quanJiao) || []
  let banJiaoMatch = string.match(banJiao) || []

  return {
    quanJiao: {
      list: quanJiaoMatch,
      len: quanJiaoMatch.length * 2,
    },
    banJiao: {
      list: banJiaoMatch,
      len: banJiaoMatch.length * 1,
    },
    total: string.length,
    //total: quanJiaoMatch.length * 2 + banJiaoMatch.length * 1,
  }
}
//正浮点数

export let positiveFloatNumber = (rule, value) => {
  if (rule.ignore == true) return Promise.resolve(true)
  if (value == 0) return Promise.resolve(true)
  if (value == null) return Promise.resolve(true)
  if (value == '') return Promise.resolve(true)
  let reg = /^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$/
  let _result = reg.test(value)

  if (_result) {
    return Promise.resolve(true)
  }
  return Promise.reject(false)
}

//正整数
export let positiveNumber = (rule, value) => {
  if (value == '' || value == null) return Promise.resolve(true)
  if (rule.ignore == true) return Promise.resolve(true)
  let reg = null
  if (!rule.includeZero) {
    reg = /^[1-9]{1,}[0-9]*$/
  } else {
    reg = /(^0{1}$)|(^[1-9]{1,}[0-9]*$)/
  }

  let _result = reg.test(value)

  if (_result) {
    return Promise.resolve(true)
  }
  return Promise.reject(false)
}

/**
 * @description 验证relation字段值如果为空的话，些项不验证，如果有值的话必须验证是否为空
 * @param {*} rule
 * @param {*} value
 * @returns Promise
 */

export const relationDate = (rule, value) => {
  if (!rule.realtion()) return Promise.resolve()
  if (!value) {
    return Promise.reject()
  } else {
    return Promise.resolve()
  }
}
/**
 *
 * @param {*} rule 验 证规则rule.value为验证最大的数字
 * @param {*} value 当前值
 * @returns Promise
 */
export const maxValue = (rule, value) => {
  if (value == '' || value == null) return Promise.resolve()

  if (Number(value) > rule.value) {
    return Promise.reject()
  }

  return Promise.resolve()
}

/**
 *
 * @description moment(value).isBefore(moment(rule.relation))
 * @param {*} rule
 * @param {*} value
 * @returns Promise
 */

export const mustBefore = (rule, value) => {
  if (!rule.realtion()) return Promise.resolve()
  if (value == null) return Promise.resolve()

  if (!value) return Promise.reject()

  let _value = value
  let _relation = rule.realtion()

  if (typeof _value == 'string' && rule.transform) {
    let _a = _value.split(':')
    _value = moment()
      .hour(_a[0])
      .minute(_a[1])
      .second(_a[2])
  }
  if (typeof _relation == 'string' && rule.transform) {
    let _a = _relation.split(':')
    _relation = moment()
      .hour(_a[0])
      .minute(_a[1])
      .second(_a[2])
  }

  if (rule.transformField) {
    if (moment(_value).isBefore(moment(_relation))) {
      return Promise.resolve()
    } else {
      return Promise.reject()
    }
  } else {
    if (_value.isBefore(_relation)) {
      return Promise.resolve()
    } else {
      return Promise.reject()
    }
  }
}

/**
 *
 * @description moment(value).isAfter(moment(rule.relation))
 * @param {*} rule
 * @param {*} value
 * @returns Promise
 */

export const mustAfter = (rule, value) => {
  if (!rule.realtion()) return Promise.resolve()
  if (value == null) return Promise.resolve()
  //console.log(rule.realtion().format('YYYY-MM-DD HH:mm:ss'))
  if (!value) return Promise.reject()

  let _value = value
  let _relation = rule.realtion()

  if (typeof _value == 'string' && rule.transform) {
    let _a = _value.split(':')
    _value = moment()
      .hour(_a[0])
      .minute(_a[1])
      .second(_a[2])
  }
  if (typeof _relation == 'string' && rule.transform) {
    let _a = _relation.split(':')
    _relation = moment()
      .hour(_a[0])
      .minute(_a[1])
      .second(_a[2])
  }
  if (rule.transformField) {
    if (moment(_value).isAfter(moment(_relation))) {
      return Promise.resolve()
    } else {
      return Promise.reject()
    }
  } else {
    if (_value.isAfter(_relation)) {
      return Promise.resolve()
    } else {
      return Promise.reject()
    }
  }
}

export const mustAfterList = (rule, value) => {
  let time_list = rule.realtion().filter((x) => !!x)

  if (time_list.length <= 0) return Promise.resolve()
  if (!value) return Promise.reject()

  let _result_list = time_list.map((x) => {
    return value.isBefore(x)
  })

  let _result = _result_list.filter((xx) => xx != true)

  if (_result.length > 0) {
    return Promise.reject()
  } else {
    return Promise.resolve()
  }
}

//只能输入数字~退格键~小数点
export const onlyEnterFloatNumber = () => {
  return {
    onKeydown: (e) => {
      let will_value = e.target.value + '' + e.key
      let will_match = will_value.match(/\./gi)
      if (will_match != null && will_match.length > 1) {
        e.preventDefault()
      }

      // if (/[^\x00-\xff]/gi.test(e.key)) {
      //   e.preventDefault()
      // }

      if (/[0-9]|\.|(Backspace)/.test(e.key)) {
        //
      } else {
        e.preventDefault()
      }
    },
  }
}
//只能输入数字~退格键
export const onlyInteger = () => {
  return {
    onKeydown: (e) => {
      if (/[0-9]|(Backspace)/.test(e.key)) {
        //
      } else {
        e.preventDefault()
      }
    },
  }
}

/**
 *
 * 文本框最大字符只能输入到60个字符
 *
 */

export const maxSearchValue = (_len = 50) => {
  let len = _len
  return {
    onPaste: (e) => {
      if (e.target.value.length >= len) {
        e.preventDefault()
      }
    },
    oninput: (e) => {
      if (e.target.value.length >= len) {
        e.target.value = e.target.value.substring(0, len)
      }
    },
    onKeydown: (e) => {
      if (/(Backspace)/.test(e.key)) {
        return
      }
      if (e.target.value.length >= len) {
        e.preventDefault()
      }
    },
  }
}

export const maxSearchValueInteger = (_len = 50) => {
  return {
    onPaste: (e) => {},
    oninput: (e) => {
      if (e.target.value.length > _len) {
        e.target.value = e.target.value.substring(0, _len)
      }

      e.target.value = e.target.value.replace(/\D/gi, '')
      e.target.value = e.target.value.replace(/^0/gi, '')
    },
    onKeydown: (e) => {
      if (/[0-9]|(Backspace)/.test(e.key)) {
        let ev_str = e.target.value
        ev_str = ev_str.replace(/\D/gi, '')
        let ev = Number(ev_str)
        e.target.value = ev
      } else {
        e.stopPropagation()
        e.stopImmediatePropagation()
        e.preventDefault()
        e.target.value = 1
        return
      }

      // e.stopPropagation()
      // e.preventDefault()
      // if (!/[0-9]|(Backspace)/.test(e.key)) {
      //   e.preventDefault()
      //  }
    },
  }
}

//验证大于某个数

export const gt = (rule, msg) => {
  // console.log(!msg, msg != 0, msg)
  // console.log(!msg)
  if (msg === null) {
    return Promise.resolve()
  }
  if (msg.length == 0) {
    return Promise.resolve()
  }

  let _value = typeof rule.value == 'function' ? rule.value() : rule.value

  if (Number(msg) > Number(_value)) {
    return Promise.resolve()
  }

  return Promise.reject(rule.message || '值须要大于' + _value)
}

export const glt = (rule, msg) => {
  // console.log(!msg, msg != 0, msg)
  // console.log(!msg)
  if (msg === null) {
    return Promise.resolve()
  }
  if (msg.length == 0) {
    return Promise.resolve()
  }
  let _value = typeof rule.value == 'function' ? rule.value() : rule.value

  if (Number(msg) >= Number(_value)) {
    return Promise.resolve()
  }

  return Promise.reject(rule.message)
}

export const notRepeat = (rule, msg) => {
  if (msg === null) {
    return Promise.resolve()
  }
  if (msg.length == 0) {
    return Promise.resolve()
  }
  let _value = typeof rule.value == 'function' ? rule.value() : rule.value

  if (_value.filter((x) => x == msg).length <= 1) {
    return Promise.resolve()
  }

  return Promise.reject(rule.message)
}

//小于等于
export const elt = (rule, msg) => {
  // console.log(!msg, msg != 0, msg)
  // console.log(!msg)
  if (msg === null) {
    return Promise.resolve()
  }
  if (msg.length == 0) {
    return Promise.resolve()
  }
  let _value = typeof rule.value == 'function' ? rule.value() : rule.value

  if (Number(msg) <= Number(_value)) {
    return Promise.resolve()
  }

  //  let _message = typeof rule.message == 'function' ? rule.message() : rule.message
  if (rule.extalMessage) {
    return Promise.reject(rule.extalMessage + _value)
  }
  return Promise.reject(rule.message)
}

//是否全部是空格
export const allSpace = (rule, msg) => {
  msg = String(msg)
  if (!msg) return Promise.resolve('ok')
  let match = msg.match(/^\s{1,}$/gi)
  if (match != null && match instanceof Array && match.length > 0) {
    return Promise.reject(rule.message)
  }
  return Promise.resolve('ok')
}

export const isJSON = (str) => {
  if (typeof str === 'string') {
    try {
      var obj = JSON.parse(str)
      if (typeof obj === 'object' && obj) {
        return true
      } else {
        return false
      }
    } catch (e) {
      return false
    }
  }
}
export const formtNumber = (num, format = '0,0') => {
  return numeral(num).format(format)
}

export const mustBetween = (rule, value) => {
  if (!rule.realtion()) return Promise.resolve()
  if (!value) return Promise.resolve()

  let range = rule.realtion()

  if (
    moment(value.format('YYYY-MM-DD HH:mm:ss')).isBetween(
      moment(range[0].format('YYYY-MM-DD HH:mm:ss')),
      moment(range[1].format('YYYY-MM-DD HH:mm:ss')),
      null,
      rule.tag || '[]'
    )
  ) {
    return Promise.resolve()
  } else {
    return Promise.reject()
  }
}
//判断img后辍是不是图片格式
export const isImage = (img) => {
  return (
    ['png', 'jpg', 'jpeg', 'webp', 'gif', 'image'].indexOf(
      img.replace(/.+\./, '').toLowerCase()
    ) !== -1
  )
}

//验证小数点后面位数长度

export const floatNumberPointLength = (rule, msg) => {
  msg = String(msg)
  let len = rule.length
  if (msg == null) return Promise.resolve()

  if (msg == '') return Promise.resolve()

  let _result = msg.split(/\./gi)

  if (_result.length < 2) return Promise.resolve()

  if (_result[1].split('').length > len || _result[1].split('').length <= 0) {
    return Promise.reject()
  }

  return Promise.resolve()
}

export const relationRequired = (rule, msg) => {
  let _relation = rule.relation()
  if (_relation == null || _relation == '' || _relation.length <= 0) {
    return Promise.resolve()
  }

  if (msg == null || msg == '' || _relation.length <= 0) {
    return Promise.reject()
  }
  return Promise.resolve()
}

/**
 * @description relation（）和value  是否同时有值或为空
 * @param {*} rule
 * @param {*} value
 */

export const isAllEmpty = (rule, value) => {
  let _another = rule.realtion()
  if (value == null && (_another == null || _another == '')) {
    return Promise.resolve()
  } else if (_another != null && (value == null || value == '')) {
    return Promise.reject()
  }

  return Promise.resolve()
}

/**
 ** 加法函数，用来得到精确的加法结果
 ** 说明：javascript的加法结果会有误差，在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
 ** 调用：accAdd(arg1,arg2)
 ** 返回值：arg1加上arg2的精确结果
 **/
export function accAdd(arg1, arg2) {
  let r1, r2, m, c
  try {
    r1 = arg1.toString().split('.')[1].length
  } catch (e) {
    r1 = 0
  }
  try {
    r2 = arg2.toString().split('.')[1].length
  } catch (e) {
    r2 = 0
  }
  c = Math.abs(r1 - r2)
  m = Math.pow(10, Math.max(r1, r2))
  if (c > 0) {
    let cm = Math.pow(10, c)
    if (r1 > r2) {
      arg1 = Number(arg1.toString().replace('.', ''))
      arg2 = Number(arg2.toString().replace('.', '')) * cm
    } else {
      arg1 = Number(arg1.toString().replace('.', '')) * cm
      arg2 = Number(arg2.toString().replace('.', ''))
    }
  } else {
    arg1 = Number(arg1.toString().replace('.', ''))
    arg2 = Number(arg2.toString().replace('.', ''))
  }
  return (arg1 + arg2) / m
}

let flag = () => {
  let _r = getUserInfo()?.permissionTagList || []

  // _r.push('editUserOrder')

  return _r
}
export let clearChildren = (_root, _parent, _index) => {
  if (_root.children) {
    _root.children.map((x, index) => {
      return clearChildren(x, _root, index)
    })
  } else {
    if (flag().indexOf(_root.name) < 0) {
      delete _parent.children[_index]
    }
  }
  return _root
}

export let deleteChildren = (_root, _parent, _index) => {
  // console.log(_root)
  _root.children?.map((x, index) => {
    deleteChildren(x, _root, index)
  })

  if (_root.children) {
    _root.children = _root.children.filter((x) => x)
    if (
      _root.children.length == 0 &&
      _parent &&
      _parent.children instanceof Array
    ) {
      _parent.children.splice(_index, 1)
    }
  }
}

export const rejectSpace = (rule, msg) => {
  if (msg === null) {
    return Promise.resolve()
  }
  if (msg.length == 0) {
    return Promise.resolve()
  }
  //let _value = typeof rule.value == 'function' ? rule.value() : rule.value

  if (/\s|　/gi.test(msg)) {
    return Promise.reject()
  } else {
    return Promise.resolve()
  }

  //return Promise.reject(rule.message)
}
/**
 *
 * @param {*} str:String 隐藏纯数字中的四位数字为*号
 * @returns
 */
export const hiddenPhone = (str = '') => {
  let _str = String(str).replace(/(\d{3})(\d{4})(\d*)/gi, '$1****$3')
  return <span>{_str}</span>
}
/**
 *
 * @param {*} _json Array<Array<T>>[[1,2,3]]
 * @param {*} _header  Array<T>[标题一,标题二,标题三]
 * @desc 把数组导出csv文件
 */
export const exportCsv = (_json, _header) => {
  // let str = _header.join(',') + '\n' + _json.join(',') + '\n'
  let str =
    _header.join(',') +
    '\n' +
    _json
      .map((x) => {
        return x.join(',') + '\n'
      })
      .join('')

  let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str)
  let link = document.createElement('a')
  link.href = uri
  link.download = '下载数据' + randomString() + '.csv'

  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}
/**
 *
 * @param {*} e:Number
 * @returns  String
 * @description 生成随机字符串
 */
export const randomString = (e) => {
  e = e || 10
  var t = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz',
    a = t.length,
    n = ''
  for (var i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a))
  return n
}
/**
 *
 * @description 把_list数组中的每一项 字符串转成数组,并且合并在一起,返回
 */
export const mergeVideoAndPictures = (_list = []) => {
  let _r = []
  for (var i = 0; i < _list.length; i++) {
    if (isJSON(_list[i])) {
      let v = JSON.parse(_list[i])
      if (v instanceof Array) {
        v.map((x) => {
          _r.push(x)
        })
      }
    }
  }
  return _r
}

/**
 *
 * @param {*} _list  列表数据
 * @param {*} _filter 过滤列表数据表达式
 * @returns  列表数据中的某一项符符_filter条件的数据
 */
export const getEnumBase = (_list, _filter) => {
  let _keys = keys(_list[0])

  let _result = _list.filter(_filter)
  if (_result.length > 0) {
    return _result[0]
  }
  let _r = {}
  for (var prop in _keys) {
    _r[prop] = null
  }
  return _r
}
/**
 *
 * @param {*} e 根据事件对象查询所需要的DOM结点
 * @param {*} _attrName  结束标识
 * @returns
 */
export let getDomAttributeByFolderId = (e, _attrName = 'folderid') => {
  let temp = e.target
  let tagName = temp.tagName
  let dataId = temp.dataset[_attrName]
  while (dataId == undefined && tagName != 'BODY') {
    tagName = temp.tagName
    if (temp?.dataset[_attrName] != undefined) {
      dataId = temp.dataset[_attrName]
    } else {
      temp = temp.parentElement
    }
  }
  return { dom: temp, dataId }
}
